package zheng.controller;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.AbstractQueryBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import zheng.controller.request.ESRequest;
import zheng.controller.vo.ESVO;
import zheng.es.BatchQueryParam;
import zheng.es.BatchQueryResult;
import zheng.es.DocumentBasicsHandle;

import java.io.IOException;
import java.util.*;

/**
 * @author: ztl
 * @date: 2025/04/03 22:38
 * @desc:
 */

@RestController
public class MyController {

    @Autowired
    RestHighLevelClient elasticsearchClient;
    @Autowired
    DocumentBasicsHandle documentBasicsHandle;

    @RequestMapping("/test")
    public String test1(){
        System.out.println("123");
        return "nih";
    }


    /**
     * 好使的，但是没有查询条件
     * @return
     * @throws Exception
     */
    @RequestMapping("/test4")
    public String test4() throws Exception {
        SearchRequest searchRequest = new SearchRequest("business_statement_record");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
                .query(QueryBuilders.matchAllQuery()) // 替换为你的实际查询
                .fetchSource(true) // 或指定字段 .fetchSource(new String[]{"field1", "field2"}, null)
                .size(100); // 设置返回条数

        searchRequest.source(sourceBuilder);

// 2. 执行查询
        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

// 3. 处理结果
        System.out.println("Total hits: " + response.getHits().getTotalHits().value);
        for (SearchHit hit : response.getHits().getHits()) {
            String sourceAsString = hit.getSourceAsString(); // 获取完整 JSON
            Map<String, Object> sourceAsMap = hit.getSourceAsMap(); // 获取 Map 结构

            System.out.println("ID: " + hit.getId());
            System.out.println("Data: " + sourceAsString);
        }

        return "";
    }

    /**
     * 查询list的数据
     * @return
     * @throws Exception
     */
    @RequestMapping("/test3")
    public Object test3(@RequestBody ESRequest esRequest) throws Exception{
        String indexName = "business_statement_record"; // 替换成你的索引名
        Integer page = esRequest.getPage();
        Integer size = esRequest.getSize();
        Integer form = esRequest.getForm();

        boolean exists = elasticsearchClient.indices().exists(
                new GetIndexRequest("indexName"),
                RequestOptions.DEFAULT
        );

        String companyId = "1";
        BatchQueryParam batchQueryParam = new BatchQueryParam();
        batchQueryParam.setIndexName(indexName);
        String[] BASE_COLUMN_LIST = {"id","order_no","company_id","pay_time_dec","category","pro_type_dec","total_price"};
        String[] exclude_COLUMN_LIST = {"order_no"};

        batchQueryParam.setIncludes(BASE_COLUMN_LIST);
        batchQueryParam.setExcludes(exclude_COLUMN_LIST);

// 构建精确查询条件
        List<AbstractQueryBuilder> queryBuilders = new ArrayList<>();

// 添加精确匹配条件
        queryBuilders.add(QueryBuilders.termQuery("order_no", 111));
        queryBuilders.add(QueryBuilders.termQuery("company_id", companyId));
        queryBuilders.add(QueryBuilders.termQuery("category", 1111));
//        queryBuilders.add(QueryBuilders.termQuery("pro_type_dec", 10)); // 注意这里是等于10，原SQL是<=10

// 添加范围查询条件
        List<RangeQueryBuilder> rangeQueries = new ArrayList<>();
//        rangeQueries.add(QueryBuilders.rangeQuery("pay_time_dec").lte(payTimeDec));
//        rangeQueries.add(QueryBuilders.rangeQuery("pro_type_dec").lte(10)); // 处理pro_type_dec <= 10

// 添加balancer的terms查询（相当于SQL中的IN）
//        queryBuilders.add(QueryBuilders.termsQuery("balancer", "企业", "企业付", "企业、个人"));

        batchQueryParam.setAbstractQueryBuilderList(queryBuilders);
        batchQueryParam.setRangeQueryBuilderList(rangeQueries);

// 不需要"或"查询条件组，所以可以设为null或空列表
        batchQueryParam.setShouldClauseGroups(null);

// 聚合查询条件（保持原样）
        SumAggregationBuilder sumAggregationBuilder = AggregationBuilders.sum("totalAmount").field("total_price").
                script(new Script(ScriptType.INLINE,"painless","doc['total_price'].value*100",new HashMap<>()));
        //查询参数
//        batchQueryParam.setAggregation(sumAggregationBuilder);
        batchQueryParam.setSize(size);
        batchQueryParam.setFrom(form);
        batchQueryParam.setUniqueColumnName("id");

        BatchQueryResult batchQueryResult = documentBasicsHandle.batchQuery(batchQueryParam);
        List<String> dataJsonList = batchQueryResult.getDataJsonList();
        List<ESVO> list = new ArrayList<>();
        for (String str : dataJsonList){
            ESVO esvo = new ESVO();
            esvo = JSON.parseObject(str,ESVO.class);
            list.add(esvo);
        }

        System.out.println(batchQueryResult);
        System.out.println("123");
        return list;
    }

    /**
     *  这个是求和的(求汇总的)
     *      符合条件的和。(加速es中100条数据，符合条件的是50条，那么这个就是50条的和)
     * @param esRequest
     * @return
     * @throws Exception
     */
    @RequestMapping("/test6")
    public Object test6(@RequestBody ESRequest esRequest) throws Exception{
        String indexName = "business_statement_record";
        Integer size = esRequest.getSize();
        Integer from = esRequest.getForm(); // 注意：应该是 from 而不是 form

        String companyId = "1";

// 1. 构建 BoolQuery（组合查询条件）
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("order_no", 111))
                .must(QueryBuilders.termQuery("company_id", companyId))
                .must(QueryBuilders.termQuery("category", 1111));

// 2. 构建聚合查询（Sum Aggregation）
        SumAggregationBuilder sumAggregation = AggregationBuilders.sum("total_sum").field("total_price");

// 3. 构建 SearchRequest
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQuery);
        sourceBuilder.aggregation(sumAggregation); // 添加聚合
        sourceBuilder.size(size); // 分页大小
        sourceBuilder.from(from); // 分页偏移

        searchRequest.source(sourceBuilder);

// 4. 执行查询
        SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);

// 5. 解析聚合结果（总和）
        Sum sumAgg = searchResponse.getAggregations().get("total_sum");
        double totalSum = sumAgg.getValue();

// 6. 获取命中的文档（分页数据）
        SearchHits hits = searchResponse.getHits();
        List<ESVO> list = new ArrayList<>();
        for (SearchHit hit : hits.getHits()) {
            String sourceAsString = hit.getSourceAsString();
            ESVO esvo = JSON.parseObject(sourceAsString, ESVO.class);
            list.add(esvo);
        }

// 7. 返回结果（可以自定义返回格式，比如包含数据和总和）
        Map<String, Object> result = new HashMap<>();
        result.put("data", list);
        result.put("totalSum", totalSum); // ES 计算的总和（不受分页影响）
        return result;
    }


    public static void main(String[] args) throws Exception{
        // 1. 初始化客户端（确保ES服务已启动）
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );

        String indexName = "test_index"; // 替换成你的索引名
        boolean exists = client.indices().exists(
                new GetIndexRequest("indexName"),
                RequestOptions.DEFAULT
        );

        System.out.println(12);
        try {
            manageIndex(client, indexName);
        } finally {
            client.close(); // 关闭连接
        }
    }

    public static void manageIndex(RestHighLevelClient client, String indexName) throws IOException {
        // 1. 检查索引是否存在（ES 7.x 必须用 IndicesExistsRequest）
        boolean exists = client.indices().exists(
                new GetIndexRequest("indexName"),
                RequestOptions.DEFAULT
        );

        if (exists) {
            // 2. 删除索引
            DeleteIndexRequest deleteRequest = new DeleteIndexRequest(indexName);
            AcknowledgedResponse deleteResponse = client.indices().delete(deleteRequest, RequestOptions.DEFAULT);
            System.out.println("删除索引成功: " + deleteResponse.isAcknowledged());
        }

        // 3. 创建索引
        CreateIndexRequest createRequest = new CreateIndexRequest(indexName);
        createRequest.settings(Settings.builder()
                .put("index.number_of_shards", 1)
                .put("index.number_of_replicas", 1)
        );

        // 4. 定义Mapping（ES 7.x 必须用 XContentBuilder）
        XContentBuilder mappingBuilder = XContentFactory.jsonBuilder()
                .startObject()
                .startObject("properties")
                .startObject("name")
                .field("type", "keyword")
                .endObject()
                .startObject("sex")
                .field("type", "long")
                .endObject()
                .startObject("age")
                .field("type", "long")
                .endObject()
                .startObject("address")
                .field("type", "text")
                .field("analyzer", "ik_max_word")
                .field("search_analyzer", "ik_smart")
                .endObject()
                .endObject()
                .endObject();

        createRequest.mapping(mappingBuilder);

        CreateIndexResponse createResponse = client.indices().create(createRequest, RequestOptions.DEFAULT);
        System.out.println("创建索引成功: " + createResponse.isAcknowledged());

        // 5. 查询索引信息
        GetIndexRequest getRequest = new GetIndexRequest(indexName);
        GetIndexResponse getResponse = client.indices().get(getRequest, RequestOptions.DEFAULT);
        System.out.println("索引Mapping: " + getResponse.getMappings().get(indexName).source());
    }

}
